﻿using DC2010.Objects;
using DC2010.Objects.Data;
using DC2010.Objects.Base;
using System;
using DC2010.Objects.Common;

namespace DC2010.Systems
{
    public class MovementSystem : BaseSystem
    {
        public override void Init()
        {

        }

        public TileData GetTile(Layer l, int X, int Y)
        {
            PartyData pd = Root.I.GameSystem.Party;
            TileData td = (TileData)GetTile(pd.Location.X, pd.Location.Y, X, Y, pd.Location.Facing, l);

            if (td == null)
            {
                td = new TileData();
                td.TileType = TileType.Wall;
                return td;
            }

            return td;
        }

        // 0  1  2  3  4
        //[ ][ ][ ][ ][ ]  4
        //[ ][ ][ ][ ][ ]  3
        //[ ][ ][ ][ ][ ]  2
        //   [ ][ ][ ]     1
        //   [ ][x][ ]     0     
        //coordinates are like this:
        // -6     -6  -5  -4  -3  -2  -1  0  +1  +2  +3  +4  +5  +6
        // -5
        // -4
        // -3
        // -2
        // -1
        //  0
        // +1
        // +2
        // +3
        // +4
        // +5
        // +6

        /// <summary>
        /// GetTile for specific direction....
        /// </summary>
        /// <param name="X">X im currently stading on.</param>
        /// <param name="Y">Y im currently standing on.</param>
        /// <param name="A">X Delta when facing to the north.</param>
        /// <param name="B">Y Delta when facing to the north.</param>
        /// <param name="dir">Target direction.</param>
        /// <param name="l">Layer...</param>
        /// <returns></returns>
        public BaseObject GetTile(int X, int Y, int A, int B, Directions dir, Layer l)
        {
            if (l!=null)
            {
                int newX = 0;
                int newY = 0;

                switch (dir)
                {
                    case Directions.North:
                        {
                            newX = X + A; newY = Y + B;
                            break;
                        }
                    case Directions.East:
                        {
                            newX = X - B; newY = Y + A;
                            break;
                        }
                    case Directions.South:
                        {
                            newX = X - A; newY = Y - B;
                            break;
                        }
                    case Directions.West:
                        {
                            newX = X + B; newY = Y - A;
                            break;
                        }
                }

                //we have new X and Y
                BaseObject bo = l[newX, newY];

                return bo;

            }

            return null;
        }

        public TileData GetCurrent()
        {
            //get party position
            DungeonLoc l = Root.I.GameSystem.Party.Location;
            FloorData fd = Root.I.FloorSystem.GetData(l.FloorId);

            return GetTile(fd.TileLayer, l.X, l.Y);
        }

        public ObjectPosition GetCornerFront(ObjectPosition op)
        {
            //everything is relative to NORTH
            //ObjectPosition.NorthEast
            
            //get party position
            DungeonLoc l = Root.I.GameSystem.Party.Location;

            switch (l.Facing)
            {
                case Directions.North:
                    {
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.NorthWest;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.NorthEast;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.SouthWest;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.SouthEast;
                        break;
                    }
                case Directions.East:
                    {
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.SouthWest;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.NorthWest;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.SouthEast;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.NorthEast;
                        break;
                    }
                case Directions.South:
                    {
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.SouthEast;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.SouthWest;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.NorthEast;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.NorthWest;
                        break;
                    }
                case Directions.West:
                    {
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.NorthEast;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.SouthEast;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.NorthWest;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.SouthWest;
                        break;
                    }

            }

            return ObjectPosition.None;
        }

        public ObjectPosition GetCornerFrontInverse(ObjectPosition op)
        {
            //everything is relative to NORTH
            //ObjectPosition.NorthEast

            //get party position
            DungeonLoc l = Root.I.GameSystem.Party.Location;

            switch (l.Facing)
            {
                case Directions.North:
                    {
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.NorthWest;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.NorthEast;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.SouthWest;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.SouthEast;
                        break;
                    }
                case Directions.East:
                    {
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.NorthWest;
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.NorthEast;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.SouthWest;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.SouthEast;
                        break;
                    }
                case Directions.South:
                    {
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.NorthWest;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.NorthEast;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.SouthWest;
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.SouthEast;
                        break;
                    }
                case Directions.West:
                    {
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.NorthWest;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.NorthEast;
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.SouthWest;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.SouthEast;
                        break;
                    }

            }

            return ObjectPosition.None;
        }

        public ObjectPosition GetCornerCurrent(ObjectPosition op)
        {
            DungeonLoc l = Root.I.GameSystem.Party.Location;

            switch (l.Facing)
            {
                case Directions.North:
                    {
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.NorthWest;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.NorthEast;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.SouthWest;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.SouthEast;
                        break;
                    }
                case Directions.East:
                    {
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.SouthWest;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.NorthWest;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.SouthEast;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.NorthEast;
                        break;
                    }
                case Directions.South:
                    {
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.SouthEast;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.SouthWest;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.NorthEast;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.NorthWest;
                        break;
                    }
                case Directions.West:
                    {
                        if (op == ObjectPosition.NorthWest) return ObjectPosition.NorthEast;
                        if (op == ObjectPosition.NorthEast) return ObjectPosition.SouthEast;
                        if (op == ObjectPosition.SouthWest) return ObjectPosition.NorthWest;
                        if (op == ObjectPosition.SouthEast) return ObjectPosition.SouthWest;
                        break;
                    }
            }

            return ObjectPosition.None;
        }
    }
}
